/******************************************************************************
 * Copyright 2022 The Airos Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "dummy_camera.h"
#include "base/device_connect/camera/device_factory.h"

#include <chrono>
#include <fstream>
#include <iostream>
#include <thread>

#include <string.h>

namespace os {
namespace v2x {
namespace device {

bool DummyCamera::Init(const std::string& config_file) {
  std::ofstream fs;
  fs.open(config_file, std::ios::in);
  if (!fs.is_open()) {
    return false;
  }
  /*
    解析config_file参数，初始化相机各项参数

    code here...

  */
  camera_map_ = {{"camera1", 1}, {"camera2", 2}, {"camera3", 3}};
  // test stream send
  uint8_t* stream1 = (uint8_t*)malloc(64);
  uint8_t* stream2 = (uint8_t*)malloc(64);
  uint8_t* stream3 = (uint8_t*)malloc(64);
  memset(stream1, 0x01, 64);
  memset(stream2, 0x02, 64);
  memset(stream3, 0x03, 64);
  stream_sender_("camera1", stream1, 64);
  stream_sender_("camera2", stream2, 64);
  stream_sender_("camera3", stream3, 64);
  free(stream1);
  free(stream2);
  free(stream3);

  return true;
}

std::shared_ptr<CameraData> DummyCamera::GetImage(
    const std::string& camera_name) {
  // 设备数据产生与格式化制备
  if (camera_map_.find(camera_name) == camera_map_.end()) {
    return nullptr;
  }

  auto camera_data = std::make_shared<CameraData>();
  /*
      填充格式化的输出数据
      data->camera_name = camera_name;
      code here...
  */
  // fill image data
  auto alloter = [](size_t size) -> void* { return (void*)malloc(size); };
  auto deleter = [](void* p) -> void {
    if (p) free(p);
  };
  camera_data->image.reset(new HWMemory(alloter, 128, deleter));
  char* data = (char*)(camera_data->image->mutable_data());
  size_t size = camera_data->image->size();
  memset(data, camera_map_[camera_name] + 1e2, size);
  // set camera name
  camera_data->sequence_num = camera_map_[camera_name];
  camera_data->device_type = ImageDeviceType::CPU;
  camera_data->device_id = 1;
  camera_data->camera_type = CameraDeviceType::IPCAMERA;
  camera_data->camera_name = camera_name;
  camera_data->mode = ImageMode::BGR;
  camera_data->height = 1080;
  camera_data->width = 1920;
  camera_data->timestamp = camera_map_[camera_name] + 1e6;

  // std::cout << camera_name << " -> sequence_num: " <<
  // camera_data->sequence_num << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));

  return camera_data;
}

CameraDeviceState DummyCamera::GetState(const std::string& camera_name) {
  if (camera_name == "camera1") {
    return CameraDeviceState::UNKNOWN;
  }
  if (camera_name == "camera2") {
    return CameraDeviceState::RUNNING;
  }
  if (camera_name == "camera3") {
    return CameraDeviceState::STOP;
  }

  return CameraDeviceState::NO_REGISTER;
}

V2XOS_CAMERA_REG_FACTORY(DummyCamera, "dummy_camera");

}  // namespace device
}  // namespace v2x
}  // namespace os
